﻿using System;
using System.Collections.Generic;
using System.IO;
using SharePoint.Orm.Metal;
using SharePoint.Orm.Metal.Rules;

namespace SharePoint.SpormRunner {
	class Program {
		static void Usage() {
			Console.WriteLine("SpormRunner: [-help] <sharepointUrl> -n [namespace] -o [outputDir] -e [excludeList] -i [includeList]");
			
		}

		private static void Help() {
			Usage();
			string helpString = 
			@"-n	This option sets the namespace of the generated classes.
-o	This option sets where the generated classes are written.
-e	This option is used to exclude items from the generation of 
	classes. This is mutually exclusive with -i option. Exclude will take
	precedence over the -i option.
-i	This option is used to generate code for specific items. This option is
	mutually exclusive with -e option.

";
			Console.Write(helpString);

		}

		static int Main(string[] args) {
		    int argslen = args.Length;
			if (argslen == 1 && args[0].ToLower() == "-help") {
				Help();
				return -1;
			}
		    if (argslen < 1 || !args[0].StartsWith("http")) {
				Usage();
				return -1;
			}
		    string codeNamespace = "", outputDir = ".";
            List<string> excludes = new List<string>();
			List<string> includes = new List<string>();
		    int namespaceIndex = Array.FindIndex(args, s => s == "-n");
		    int outputIndex = Array.FindIndex(args, s => s == "-o");
		    int excludeIndex = Array.FindIndex(args, s => s == "-e");
			int includeIndex = Array.FindIndex(args, s => s == "-i");
            if(namespaceIndex != -1) {
                if(namespaceIndex +1 < argslen && !args[namespaceIndex+1].StartsWith("-"))
                    codeNamespace = args[namespaceIndex + 1];
            }
			if(outputIndex != -1) {
                if (outputIndex + 1 < argslen && !args[outputIndex + 1].StartsWith("-"))
                    outputDir = args[outputIndex + 1];
			}
            if (excludeIndex != -1) {
                int offset = 1;
                while(excludeIndex + offset < argslen && !args[excludeIndex + offset].StartsWith("-")) {
                    excludes.Add(args[excludeIndex + offset]);
                    offset++;
                }
            }
			if(includeIndex != -1) {
				int offset = 1;
				while(includeIndex + offset < argslen && !args[excludeIndex + offset].StartsWith("-")) {
					includes.Add(args[includeIndex + offset]);
					offset++;
				}
			}
		    CodeGenerator generator = new CodeGenerator();
			string stringUrl = args[0];

			CodeGeneratorConfiguration config = new CodeGeneratorConfiguration {
				Url = stringUrl,
				DataContextOutputDirectory = Path.Combine(outputDir, @"_generated"),
				ContentTypeOutputDirectory = Path.Combine(outputDir, @"_generated\ContentTypes"),
				ListOutputDirectory = Path.Combine(outputDir, @"_generated\Lists")
			};
			if (!string.IsNullOrEmpty(codeNamespace)) {
				config.DataContextNamespaceName = codeNamespace;
				config.ListNamespaceName = codeNamespace + ".List";
				config.ContentTypeNamespaceName = codeNamespace + ".ContentType";

			}
			if(excludes.Count == 0 && includes.Count == 0)
				config.AddListRule(new ListIncludeRule("*"));
			else if(excludes.Count > 0) {
				foreach (string rule in excludes)
					config.AddListRule(new ListExcludeRule(rule));
				config.AddListRule(new ListIncludeRule("*"));
			}else if(includes.Count > 0) {
				foreach(string rule in includes)
					config.AddListRule(new ListIncludeRule(rule));
			}
            
            try {
                generator.Generate(config);
            }catch(Exception e) {
                Console.WriteLine("Error occurred while trying to generate entities {0}", e);
            }
		    return 0;
		}
	}
}
